package io.awen.modules.sign.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.awen.common.exception.RRException;
import io.awen.common.utils.PageUtils;
import io.awen.common.utils.Query;
import io.awen.modules.sign.dao.SignContainerDao;
import io.awen.modules.sign.entity.*;
import io.awen.modules.sign.qo.SignContainerQo;
import io.awen.modules.sign.service.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;


@Service("signContainerService")
public class SignContainerServiceImpl extends ServiceImpl<SignContainerDao, SignContainerEntity> implements SignContainerService {

    @Autowired
    private SignContainerDao signContainerDao;
    @Autowired
    private SignContainerRealtimeLiquidLevelService signContainerRealtimeLiquidLevelService;

    private HashMap<String, SignContainerEntity> sensorContainerMap;
    private ScheduledExecutorService scheduledExecutorService;

    @Override
    public Map<String, SignContainerEntity> getSensorContainerMap() {
        return sensorContainerMap;
    }

    @Override
    public SignContainerEntity getBySensorId(String sensorId) {
        if (StringUtils.isBlank(sensorId)) {
            throw new RRException("sensorId不能为空");
        }
        return signContainerDao.getBySensorId(sensorId);
    }

    @Autowired
    private SignContainerAlarmService signContainerAlarmService;

    @Autowired
    private SignUnitService signUnitService;

    @Autowired
    private SignFleetService signFleetService;

    @Autowired
    private SignVillageTownService signVillageTownService;

    @Autowired
    private SignContainerService signContainerService;

    @PostConstruct
    private void init() {
        sensorContainerMap = new HashMap<>(400);

        List<SignContainerEntity> list = list(
                new QueryWrapper<SignContainerEntity>().lambda()
        );
        for (SignContainerEntity entity : list) {
            // 获取容器当前液位计监测值
            entity.setSensorValue(entity.getRealtimeLiquidLevel());
            entity.setDataTime(new Date());
            sensorContainerMap.put(entity.getSensorId(), entity);
        }

        // 设置定时器，不断刷新容器中液位计的监测值
//        scheduledExecutorService = new ScheduledExecutorService();
    }

    @Override
    public SignContainerEntity findContainer(String sensorId) {
        return sensorContainerMap.get(sensorId);
    }

    @Override
    public SignContainerEntity findContainer(Long id) {
        Iterator<SignContainerEntity> iterator = sensorContainerMap.values().iterator();
        while (iterator.hasNext()) {
            SignContainerEntity container = iterator.next();
            if (container.getId().equals(id)) {
                return container;
            }
        }
        return null;
    }

    @Override
    public SignContainerEntity findAllContainer(Long id) {

        return signContainerService.getById(id);
    }

    @Override
    public SignContainerEntity findContainerById(Long id) {
        return getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSensorValue(String sensorId, Double value, Date dataTime) {
        SignContainerEntity container = sensorContainerMap.get(sensorId);
        container.setSensorValue(value);
        if (dataTime == null) {
            dataTime = new Date();
        }
        container.setDataTime(dataTime);


        //更新最新液位
        SignContainerEntity entity = this.getBySensorId(sensorId);
        if (entity != null) {
            entity.setRealtimeLiquidLevel(value);
            signContainerDao.updateById(entity);
        }
//        sensorContainerMap.put(sensorId,container);
        signContainerAlarmService.juegeAlarm(container);


        //同步到数据库sign_container_realtime_liquid_level
        SignContainerRealtimeLiquidLevelEntity levelEntity = new SignContainerRealtimeLiquidLevelEntity();
        levelEntity.setContainerId(container.getId());
        levelEntity.setSensorId(container.getSensorId());
        levelEntity.setRealtimeLiquidLevel(value);
        levelEntity.setName(container.getName());
        signContainerRealtimeLiquidLevelService.insert(levelEntity);
    }


    @Override
    public PageUtils queryPage(SignContainerQo qo) {
        IPage<SignContainerEntity> page = this.page(
                new Query<SignContainerEntity>().getPage(qo),
                new QueryWrapper<SignContainerEntity>().lambda()
                        .eq(qo.getCtUnitId() != null, SignContainerEntity::getCtUnitId, qo.getCtUnitId())
                        .eq(qo.getCtFleetId() != null, SignContainerEntity::getCtFleetId, qo.getCtFleetId())
                        .eq(StringUtils.isNotBlank(qo.getStatus()), SignContainerEntity::getStatus, qo.getStatus())
                        .ge(qo.getStartTime() != null, SignContainerEntity::getCreateTime, qo.getStartTime())
                        .le(qo.getEndTime() != null, SignContainerEntity::getCreateTime, qo.getEndTime())
                        .like(StringUtils.isNotBlank(qo.getName()), SignContainerEntity::getName, qo.getName())
                        .like(StringUtils.isNotBlank(qo.getJiedao()), SignContainerEntity::getJiedao, qo.getJiedao())
                        .like(StringUtils.isNotBlank(qo.getSheqv()), SignContainerEntity::getSheqv, qo.getSheqv())
                        .orderByDesc(SignContainerEntity::getId)
        );

        for (SignContainerEntity entity : page.getRecords()) {
            SignUnitEntity unit = signUnitService.getById(entity.getCtUnitId());
            entity.setUnit(unit);
            SignFleetEntity fleetUnit = signFleetService.getById(entity.getCtFleetId());
            entity.setFleetUnit(fleetUnit);
            SignVillageTownEntity village = signVillageTownService.getById(entity.getVillageId());
            entity.setVillageTown(village);
        }

        return new PageUtils(page);
    }

    @Override
    public void saveAndCache(SignContainerEntity signContainer) {
        save(signContainer);
        sensorContainerMap.put(signContainer.getSensorId(), signContainer);
    }

    @Override
    public void updateAndCache(SignContainerEntity signContainer) {
        updateById(signContainer);

        SignContainerEntity byId = getById(signContainer.getId());

        String sensorId = byId.getSensorId();
        if (sensorId != null&&sensorContainerMap.get(sensorId).getSensorValue()!=null) {
            byId.setSensorValue(sensorContainerMap.get(sensorId).getSensorValue());
            sensorContainerMap.put(sensorId, byId);
        }
    }

    @Override
    public void updateWithoutSensor(SignContainerEntity signContainer) {
        updateById(signContainer);
//        SignContainerEntity byId = getById(signContainer.getId());
//        byId.setSensorValue(sensorContainerMap.get(byId.getSensorId()).getSensorValue());
//        sensorContainerMap.put(byId.getSensorId(), byId);
    }

    @Override
    public int total(SignContainerQo qo) {
        int count = this.count(
                new QueryWrapper<SignContainerEntity>().lambda()
                        .eq(qo.getCtUnitId() != null, SignContainerEntity::getCtUnitId, qo.getCtUnitId())
                        .ge(qo.getStartTime() != null, SignContainerEntity::getCreateTime, qo.getStartTime())
                        .le(qo.getEndTime() != null, SignContainerEntity::getCreateTime, qo.getEndTime())
        );
        return count;
    }

}